<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <script>
       //同步与异步相关面试题？
 /*      console.log(1); 
      setTimeout(()=>{
       console.log(2); 
      },0)
       console.log(3); 
      //输出 1，3，2 */

       //1.1 输出结果,并写出为什么 ？
    /*    for (var i = 0; i <= 5; i++) {
          // console.log(16,i)
             setTimeout(() => {
                    console.log(18,i);
                }, i * 1000)
        }
        console.log(i); //先输出6，然后间隔1秒输出6个6  */

       //1.2 以上代码如果想输出6,0,1,2,3,4,5,怎么实现?
       //自执行函数 (()=>{})() 或者 (()=>{}())
      /*  var a=2;
       (function (b){
          console.log(b);
       })(a) */
      

    /*  for (var i = 0; i <= 5; i++) {
            //a是形参
            ((a) => { 
                setTimeout(() => {
                    console.log(a);
                }, a* 1000)
            })(i); //i是实参,接受外部参数

        }
        console.log(i); */

        
        // 输出结果6,0,1,2,3,4,5
        // 因为for循环是同步,定时器是异步,所以输出6个0。通过自执行函数可实现((参数)=>{})(接受外部参数)。


        //1.3 通过let也可实现,let是块级作用域
    /*    for (let i = 0; i <= 5; i++) {
            setTimeout(() => {
                    console.log(i);
                }, i * 1000)
          }
          console.log(i); //但是这里会报错 */

        //3.1  event loop 事件循环题

      /*  setTimeout(() => {
            console.log(1);
        }, 0)
        new Promise((resolve, reject) => {
            console.log(2);  //同步
            resolve()
        }).then(() => {
            console.log(4);
        })
        console.log('3'); //同步 ,输出结果 2,3,4,1   */

       //执行优先级 1.同步(promise里除了resolve的.then是异步请求。其它写的都是同步)>异步(微任务[promise的.then,async,await,axios]>宏任务[定时器,事件函数,ajax])
  

     //3.2 输出结果
    /*   let aa = async () => {
        console.log(3); //没有await前都是同步
       await console.log(5);  //await后面要的是异步请求结果,如果不是，会直接返回相当于同步。
      // await setTimeout(() => { //await 后面都是异步的，定时器是宏任务
      //     console.log(2);
      //   }, 0);
       console.log(4);   //微任务
      }
      aa()
      console.log(1);  //前面是3，5，1，4 后面的是3,1,4,2 */
 
    //3.3 输出结果
      /*  new Promise((resolve, reject) => {
          resolve(
            (()=>{  //这里是自执行函数
              console.log(1);
              return 2  //返回结果
            })()
          );
            console.log(3);  //同步
        }).then((arg) => {
            console.log(arg);
        })
        setTimeout(() => {
            console.log(4);
        }, 0)
        console.log(5); //输出结果 1,3,5,2,4  */


      // 3.4 事件循环进阶题
   async function async1() {
        console.log('1') //-2
        await async2()  //注意此处加await，会阻塞后面代码执行。不加的话不影响
        console.log('2') //-6
      }
      async function async2() {
        console.log('3')  //-3
      }

      console.log('4') //同步-1

      setTimeout(function() {
        console.log('5') //-8
      }, 0)

      async1() //同步-2

      new Promise(function(resolve) {
        console.log('6')  //注意此处，在这里也是同步 -4
        resolve()  //这是异步
      }).then(function() {
        console.log('7') //-7
      })
      console.log('8')   //同步 5 

         //最后返回结果 4,1,3,6,8,2,7,5
    

     /*  //4.面试题-你对事件循环evnet loop怎么理解？
         Event Loop（事件循环）解释：  js是一个单线程,异步io语言。单线程意味着堵塞,为了解决堵塞问题,js把任务分成了同步和异步任务，它们会分别进入不同的执行“场所”，同步进入主线程，异步进入任务队列。主线程内的任务执行完毕为空，就去任务队列读取对应的函数，进入主线程执行。只要主线程空了，就会读取任务列队，上述过程会不断重复，也就是常说的Event Loop（事件循环）。

         JS异步还有一个机制，就是遇到宏任务，先执行宏任务，将宏任务放入宏任务队列，然后再执行微任务，将微任务放入微任务队列，但是，这两个队列不是一个队列。当你往外拿的时候先从微任务队列里拿这个回调函数，然后再从宏任务的队列里拿宏任务的回调函数，也就是宏任务是先进后出,微任务后进先出。

         咱们看代码执行顺序的时候是 ：主线程(同步任务) > 微任务(promise,async,await) > 宏任务(定时器,ajax,事件等)

        参考链接-https://blog.csdn.net/weixin_43638968/article/details/108941287
       */

    </script>
</body>

</html>